package lasec.servlet;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lasec.connect.DBManager;

import com.restfb.Connection;
import com.restfb.DefaultFacebookClient;
import com.restfb.DefaultJsonMapper;
import com.restfb.DefaultWebRequestor;
import com.restfb.FacebookClient;
import com.restfb.Parameter;
import com.restfb.WebRequestor;
import com.restfb.exception.FacebookException;
import com.restfb.exception.FacebookOAuthException;
import com.restfb.types.User;

/**
 * Servlet implementation class LoginServlet
 */
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private DBManager manage;

	public void init() throws ServletException {
		super.init();
		manage = new DBManager();
		System.out.println("init()" + this.getClass());
	}

	/**
	 * @see Servlet#destroy()
	 */
	public void destroy() {
		System.out.println("Destroying..." + this.getClass());
		manage = null;
	}

	/**
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void processRequest(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		RequestDispatcher rd = null;

		String uid = request.getParameter("uid");
		String access_token = request.getParameter("access_token");
		FacebookClient fbClient = null;
		User user = null;
		Connection<User> myFriends = null;
		
		try {
			WebRequestor webRequestor = new DefaultWebRequestor() {
				protected HttpURLConnection openConnection(URL url) throws IOException {
					System.setProperty("java.net.useSystemProxies", "true");
					List l = null;
					SocketAddress addr;
					Proxy proxy = null;
					
					try {
						l = ProxySelector.getDefault().select(new URI("http://www.facebook.com"));
					} catch (URISyntaxException e) {
						e.printStackTrace();
					}
					
					for (Iterator<List> iter = l.iterator(); iter.hasNext();) {
						proxy = (Proxy) iter.next();
					}
					
					addr = (InetSocketAddress) proxy.address();

//					if (proxy.address() == null) {
//						System.out.println("Proxy undetected");
//						return (HttpURLConnection) url.openConnection();
//					} else {
//						System.out.println("Proxy detected");
//						addr = new InetSocketAddress("proxy.dlsu.edu.ph", 80);
//						proxy = new Proxy(Proxy.Type.HTTP, addr);
//						return (HttpURLConnection) url.openConnection(proxy);
//					}
					if (addr == null) {
						addr = new InetSocketAddress("proxy.dlsu.edu.ph", 80);
						proxy = new Proxy(Proxy.Type.HTTP, addr);
					}
					
					return (HttpURLConnection) url.openConnection(proxy);
				}
			};
			// Initialize restfb with access token.
			fbClient = new DefaultFacebookClient(access_token);
//			fbClient = new DefaultFacebookClient(access_token, webRequestor, new DefaultJsonMapper());
			// Fetch user id and user's facebook friends connection
			user = fbClient.fetchObject(uid, User.class, Parameter.with(
					"fields",
					"id, first_name, last_name, hometown, birthday, gender"));
			myFriends = fbClient.fetchConnection(uid
					+ "/friends", User.class,
					Parameter.with("fields", "id"));
			
			if ((user.getId()).equals(uid)) {
				if (manage.isUserExist(uid)) {
					manage.addUserFriends(uid, myFriends);
					user = null;
					fbClient = null;
					myFriends = null;
					rd = getServletContext().getRequestDispatcher("/");
					rd.forward(request, response);
				} else {
					System.out.println("User does not exist");
					String lastname = user.getLastName();
					String firstname = user.getFirstName();
					String hometown = user.getHometownName();
					System.out.println(hometown);
					if (hometown == null) {
						System.out.println("User has no country");
						hometown = "Philippines";
					} else {
						StringBuffer nationality = new StringBuffer(hometown);
						System.out.println(nationality);
						int i = nationality.lastIndexOf(",");
						hometown = nationality.substring(i+1, nationality.length()).trim();
						nationality = null;
					}
					Calendar cal = new GregorianCalendar();
					Date dob = user.getBirthdayAsDate();
					int year = cal.get(Calendar.YEAR);
					int birthYear = year - (1900 + dob.getYear());

					String gender = user.getGender();

					manage.addUser(uid, lastname, firstname, hometown,
							birthYear, gender);
					
					manage.addUserFriends(uid, myFriends);
					
					user = null;
					fbClient = null;
					myFriends = null;
					cal = null;
					dob = null;
					rd = getServletContext().getRequestDispatcher(
							"/JSP/genre.jsp");
					rd.forward(request, response);
				}
			} else {
				user = null;
				fbClient = null;
				myFriends = null;
				rd = getServletContext().getRequestDispatcher("/JSP/error.jsp");
				rd.forward(request, response);
			}

		} catch (FacebookOAuthException ex) {
			ex.printStackTrace();
			user = null;
			fbClient = null;
			myFriends = null;
			rd = getServletContext().getRequestDispatcher("/JSP/error.jsp");
			rd.forward(request, response);
		} catch (FacebookException ex) {
			ex.printStackTrace();
			user = null;
			fbClient = null;
			myFriends = null;
			rd = getServletContext().getRequestDispatcher("/JSP/error.jsp");
			rd.forward(request, response);
		} catch (Exception e) {
			e.printStackTrace();
			user = null;
			fbClient = null;
			myFriends = null;
			rd = getServletContext().getRequestDispatcher("/JSP/error.jsp");
			rd.forward(request, response);
		}
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		processRequest(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		processRequest(request, response);
	}

}
